<?php

// 验证码类
class Captcha
{

    protected int $width;
    protected int $height;
    protected GdImage $image;
    protected int $len = 5;
    protected string $code = "";

    public function __construct(int $width = 100, int $height = 30)
    {
        $this->width = $width;
        $this->height = $height;
    }

    // 渲染显示验证码
    public function render(): string
    {
        $this->fill();
        $this->pixel();
        $this->line();
        $this->text();
        $this->show();
        return $this->code;
    }

    protected function show()
    {
        header('Content-type:image/png');
        imagepng($this->image);
    }

    protected function fill()
    {
        // 创建画布并填充颜色
        $image = imagecreatetruecolor($this->width, $this->height);
        imagefill($this->image = $image, 0, 0, imagecolorallocate($image, 200, 200, 200));
    }

    public function __destruct()
    {
        imagedestroy($this->image);
    }

    // 画线条
    protected function line()
    {
        for ($i = 0; $i < 6; $i++) {
            // 设置线条的宽度
            imagesetthickness($this->image, mt_rand(1, 3));
            imageline($this->image,
                mt_rand(0, $this->width),
                mt_rand(0, $this->height),
                mt_rand(0, $this->width),
                mt_rand(0, $this->height),
                $this->color()
            );
        }
    }

    // 生成随机颜色
    protected function color(): int
    {
        return imagecolorallocate($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
    }

    // 绘制干扰点
    protected function pixel()
    {
        for ($i = 0; $i < 300; $i++) {
            imagesetpixel($this->image, mt_rand(0, $this->width), mt_rand(0, $this->height), $this->color());
        }
    }

    // 绘制验证码
    protected function text()
    {
        $font = realpath('MAIAN.TTF');
        $x = $this->width / $this->len;
        $text = 'abcdefghijklmnopqrstvwxyz';
        $angel = mt_rand(-20, 20);
        $box = imagettfbbox(20, $angel, $font, 'A');
        $width = $box[2] - $box[0];
        $height = $box[7] - $box[0];
        for ($i = 0; $i < $this->len; $i++) {
            $code = strtoupper($text[mt_rand(0, strlen($text) - 1)]);
            $this->code .= $code;
            imagettftext($this->image, 20, $angel, $x * $i + 5, ($this->height / 2) - $height / 2, $this->textColor(), $font,
               $code);
        }
    }

    protected function textColor()
    {
        return imagecolorallocate($this->image, 100, 100, 100);
    }
}